//
//  ViewController.swift
//  PDF2PNG
//
//  Created by Jarvis on 08/05/2017.
//  Copyright © 2017 Jarvis. All rights reserved.
//

import UIKit
import SnapKit
import CoreGraphics
import MBProgressHUD
import SKPhotoBrowser


class ConvertViewController: ViewController {

    let cellID = "pageCellID"
    
    var imageView: UIImageView!
    var tableView: UITableView!
    var collectionView: UICollectionView!
    
    var editView: UIView!
    var selectAllButton: UIButton!
    var mergeButton: UIButton!
    var selectCountLabel: UILabel!
    
    var pdfPages = [PageInfo]()
    
    var pdfURL: URL?
//    var fileInfo: FileInfo?
    
    var pageIndex: Int = 0
    var pageCount: Int = 0
    var pdfDoc: CGPDFDocument?
    
    var enableSelectPage: Bool = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.title = "Pages".localized()
        self.view.backgroundColor = UIColor.gray;
        let rightItem = UIBarButtonItem(title: "Select".localized(), style: .plain, target: self, action: #selector(rightItemPressed(_:)))
        self.navigationItem.rightBarButtonItem = rightItem;
        

//        imageView = UIImageView()
//        self.view.addSubview(imageView)
//        imageView.contentMode = .scaleAspectFit
//        imageView.frame = CGRect(x: 10, y: 80, width: self.view.bounds.size.width-20, height: self.view.bounds.size.height-100)
//        imageView.backgroundColor = UIColor.orange
        
//        prepareTableView()
        prepareCollectionView();
        prepareEditView()

        
        loadPDF(fileURL: pdfURL!);
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
    
    func prepareTableView() {
        tableView = UITableView();
        view.addSubview(tableView);
        tableView.snp.makeConstraints { (make) in
            make.edges.equalTo(UIEdgeInsets.zero)
        }
        
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID");
        tableView.delegate = self;
        tableView.dataSource = self;
        
    }
    
    //MARK: prepare
    func prepareCollectionView() {

        let layout = UICollectionViewFlowLayout()
        let margin: CGFloat = 15
        let itemW: CGFloat = pageCollectionCellWidth
        let itemH: CGFloat = itemW + 30
        
        layout.itemSize = CGSize(width: itemW, height: itemH)
        layout.sectionInset = UIEdgeInsetsMake(margin, margin, margin, margin)
        layout.minimumInteritemSpacing = margin
        
        collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
        view.addSubview(collectionView!)
        collectionView!.delegate = self
        collectionView!.dataSource = self
        collectionView!.register(PDFPageCell.self, forCellWithReuseIdentifier: cellID)
        collectionView!.backgroundColor = UIColor(red: 0.9, green: 0.9, blue: 0.9, alpha: 1.0)
        collectionView!.snp.makeConstraints { (make) in
            make.edges.equalTo(UIEdgeInsets.zero)
        }
    }
    
    
    func prepareEditView() {
        editView = UIView()
        self.view.addSubview(editView)
        editView.backgroundColor = UIColor(red: 0.8, green: 0.8, blue: 0.8, alpha: 1.0)
        editView.snp.makeConstraints { (make) in
            make.height.equalTo(44)
            make.left.equalToSuperview()
            make.right.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        
        
        let leftButton = UIButton()
        editView.addSubview(leftButton)
        leftButton.setImage(UIImage(named: "select_all_normal"), for: .normal)
        leftButton.setImage(UIImage(named: "select_all_selected"), for: .selected)
        leftButton.setTitleColor(UIColor.green, for: .normal)
        leftButton.addTarget(self, action: #selector(selectAllButtonPressed(_:)), for: .touchUpInside)
        leftButton.snp.makeConstraints { (make) in
            make.leftMargin.equalTo(10)
            make.top.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        
        let rightButton = UIButton()
        editView.addSubview(rightButton)
        rightButton.setTitle("Merge".localized(), for: .normal)
        rightButton.setTitleColor(UIColor(red:0.10, green:0.68, blue:0.35, alpha:1.0), for: .normal)
        rightButton.setTitleColor(UIColor(red:0.10, green:0.68, blue:0.35, alpha:0.4), for: .disabled)
        rightButton.addTarget(self, action: #selector(mergeButtonPressed(_:)), for: .touchUpInside)
        rightButton.snp.makeConstraints { (make) in
            make.rightMargin.equalTo(-10)
            make.top.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        
        let middleLabel = UILabel()
        editView.addSubview(middleLabel)
        middleLabel.text = "-0-"
        middleLabel.textColor = UIColor.darkGray
        middleLabel.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
        
        selectAllButton = leftButton
        mergeButton = rightButton
        selectCountLabel = middleLabel
        
        editView.isHidden = true
    }
    
    //MARK: eventes
    @objc func rightItemPressed(_ buttonItem: UIBarButtonItem) {
        editView.isHidden = !editView.isHidden
        
        enableSelectPage = !enableSelectPage
        
        if enableSelectPage {
            buttonItem.title = "Cancel".localized()
            
            Tracker.enableSelect()
        }else {
            buttonItem.title = "Select".localized()
            
            Tracker.disableSelect()
        }
     
        updateSelectedPagesInfo()
        collectionView.reloadData()
    }
    
    @objc func selectAllButtonPressed(_ button: UIButton) {
        button.isSelected = !button.isSelected
        
        if (button.isSelected) {
            for page in pdfPages {
                page.isSelected = true
            }
            
            Tracker.selectAllPages()
        }else {
            for page in pdfPages {
                page.isSelected = false
            }
            
            Tracker.deselectAllPages()
        }
        
        updateSelectedPagesInfo()
        collectionView.reloadData()
    }
    
    @objc func mergeButtonPressed(_ button: UIButton) {
        if (pdfPages.count > 0) {
            
            var selectedPages = [PageInfo]()
            for page in pdfPages {
                if page.isSelected {
                    selectedPages.append(page)
                }
            }
            if selectedPages.count < 2 {
                Toast.showMessage(message: "Please select at least 2 pages.".localized())
                return
            }
            
            if selectedPages.count > 20 {
                Toast.showMessage(message: "Maximum support of 20 pages.".localized())
                return
            }
            
            // 显示加载遮罩
            MBProgressHUD.showAdded(to: UIApplication.shared.keyWindow!, animated: true);
            mergeImages(images: selectedPages, completeHandler: {[weak self] (newImage) in
                
                Tracker.mergePages(numOfPages: selectedPages.count, totalOfPages: (self?.pdfPages.count)!)
                
                let preview = PreviewViewController()
                preview.previewImage = newImage
                
                DispatchQueue.main.async {
                    self?.navigationController?.pushViewController(preview, animated: true)
                    MBProgressHUD.hide(for: UIApplication.shared.keyWindow!, animated: true)
                }
            })
        }
    }
    
    
    func mergeImages(images: [PageInfo], completeHandler: ((UIImage) -> ())?) {
        
        DispatchQueue.global().async {
            
            let firstImage = images.first!
            let imageWidth:CGFloat = CGFloat(firstImage.width)
            let imageHeight:CGFloat = CGFloat(firstImage.height)
            
            let newSize = CGSize(width: imageWidth,
                                 height: imageHeight * CGFloat(images.count))
            
            UIGraphicsBeginImageContextWithOptions(newSize, true, UIScreen.main.scale);
            
            var i:Int = 0;
            for pageInfo in images {
                
                if let image = pageInfo.image {
                    let rect = CGRect(x: 0, y: (imageHeight * CGFloat(i)), width: imageWidth, height: imageHeight)
                    
                    image.draw(in: rect)
                }
                
                i += 1;
            }
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            
            UIGraphicsEndImageContext()
            
            if let handler = completeHandler {
                handler(newImage!)
            }
        }
        
    }
    
    func loadPDF(fileURL: URL, startAt: Int, length: Int) {
        if (pdfURL == nil) {
            print("文件路径错误")
            return;
        }
        
        // 显示加载遮罩
        MBProgressHUD.showAdded(to: UIApplication.shared.keyWindow!, animated: true);
        
        // 异步解析pdf每一页
        DispatchQueue.global().async {[weak self] in
            do {
                let pdfdata = try Data(contentsOf: fileURL)
                
                let pdfData = pdfdata as CFData
                let provider:CGDataProvider = CGDataProvider(data: pdfData)!
                
                if let pdf = CGPDFDocument(provider) {
                    
                    print("文档总页数：\(pdf.numberOfPages)")
                    
                    // 最多支持20页
                    let count = min(pdf.numberOfPages - (startAt+1), length)
                    if count <= 0 {
                        print("没有更多了");
                        Toast.hideOnMainThread()
                        return
                    }
                    
                    self?.pdfDoc = pdf;
                    self?.pageCount = count;
                    
                    for index in startAt...(startAt+count) {
                        if let image = self?.convertPDFToImage(atPageIndex: index) {
                            let pageInfo = PageInfo(image: image, index: index)
                            self?.pdfPages.append(pageInfo);
                        }else {
                            print("解析错误：第\(index)页");
                            break;
                        }
                    }
                    
                    
                    DispatchQueue.main.async {
                        self?.collectionView.reloadData()
                        MBProgressHUD.hide(for: UIApplication.shared.keyWindow!, animated: true)
                    }
                    
                    print("pdf文件解析成功：\(count)页");
                }
                
            } catch let error as NSError  {
                print("解析pdf文件失败：\(error)")
                DispatchQueue.main.async {
                    MBProgressHUD.hide(for: UIApplication.shared.keyWindow!, animated: true)
                }
            }
        }
        
        
    }
    
    func loadPDF(fileURL: URL) {
        if (pdfURL == nil) {
            print("文件路径错误")
            return;
        }
        
        // 显示加载遮罩
        MBProgressHUD.showAdded(to: UIApplication.shared.keyWindow!, animated: true);
        
        // 异步解析pdf每一页
        DispatchQueue.global().async {[weak self] in
            do {
                let pdfdata = try Data(contentsOf: fileURL)
                
                let pdfData = pdfdata as CFData
                let provider:CGDataProvider = CGDataProvider(data: pdfData)!
                
                if let pdf = CGPDFDocument(provider) {
                    
                    print("文档总页数：\(pdf.numberOfPages)")
                    
                    // 最多支持20页
                    let count = min(pdf.numberOfPages, 30)
                    
                    self?.pdfDoc = pdf;
                    self?.pageCount = count;
                    
                    for index in 1...count {
                        if let image = self?.convertPDFToImage(atPageIndex: index) {
                            let pageInfo = PageInfo(image: image, index: index)
                            self?.pdfPages.append(pageInfo);
                        }else {
                            print("解析错误：第\(index)页");
                            break;
                        }
                    }
                    
                    
                    DispatchQueue.main.async {
                        self?.collectionView.reloadData()
                        MBProgressHUD.hide(for: UIApplication.shared.keyWindow!, animated: true)
                    }
                    
                    print("pdf文件解析成功：\(count)页");
                }
                
            } catch let error as NSError  {
                print("解析pdf文件失败：\(error)")
                DispatchQueue.main.async {
                    MBProgressHUD.hide(for: UIApplication.shared.keyWindow!, animated: true)
                }
            }
        }
    }
    
    func convertPDFToImage(atPageIndex: Int) -> UIImage! {

        if let pdf = pdfDoc {
            let pdfPage:CGPDFPage = pdf.page(at: atPageIndex)!
            let pageRect:CGRect = pdfPage.getBoxRect(.mediaBox)
            
//            print("\(pageRect.width) by \(pageRect.height)")
            
//            if #available(iOS 10.0, *) {
//                let renderer = UIGraphicsImageRenderer(size: pageRect.size)
//                let pdfImage = renderer.image(actions: { (context) in
//                    UIColor.white.set()
//                    
//                    context.fill(pageRect)
//                    
//                    context.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
//                    context.cgContext.scaleBy(x: 1.0, y: -1.0)
//                    context.cgContext.concatenate(pdfPage.getDrawingTransform(.artBox, rect: pageRect, rotate: 0, preserveAspectRatio: true))
//                    
//                    context.cgContext.drawPDFPage(pdfPage)
//                })
//            } else {
//                // Fallback on earlier versions
//            }
            
            let scale = Device.screenNativeScale()
            UIGraphicsBeginImageContextWithOptions(pageRect.size, true, scale)
            print(">> pageRect: \(pageRect), opaque: \(true), scale: \(scale)")
            
            let context:CGContext = UIGraphicsGetCurrentContext()!
            
            context.setFillColor(red: 1.0,green: 1.0,blue: 1.0, alpha: 1.0)
            context.fill(pageRect)
            
            context.saveGState()
            context.translateBy(x: 0.0, y: pageRect.size.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.concatenate(pdfPage.getDrawingTransform(.mediaBox, rect: pageRect, rotate: 0, preserveAspectRatio: true))
            
            context.drawPDFPage(pdfPage)
            context.restoreGState()
            
            let pdfImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            
            return pdfImage;
        }
        
        return nil;
    }
    
    func updateSelectedPagesInfo() {
        
        var selectedCount = 0;
        for page in pdfPages {
            if page.isSelected {
                selectedCount += 1
            }
        }
        
        // 更新选中数量
        selectCountLabel.text = String(format: "- %d -", selectedCount)
        
        // 数量少于2或大于20不能使用合成功能
        mergeButton.isEnabled = selectedCount >= 2 && selectedCount <= 20

        // 更新全选按钮
        selectAllButton.isSelected = selectedCount == pdfPages.count;
    }
    
    func resetSelectedPagesInfo() {
        editView.isHidden = true
        enableSelectPage = false
        
        
        collectionView.reloadData()
    }

    // 创建图片模型数组
    func createSKPhotos() -> [SKPhotoProtocol] {
        var photos = [SKPhotoProtocol]()
        for page in pdfPages {
            let photo = SKPhoto.photoWithImage(page.image!)
//            photo.caption = String(format: "page %d", page.index!)
            
            photos.append(photo)
        }
        
        return photos
    }
}

extension ConvertViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return pageCount;
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellID");
        
        cell?.textLabel?.text = String(format: "第%d页", indexPath.row + 1)
        
        if pdfPages.count > (indexPath.row+1) {
            let page = pdfPages[indexPath.row];
            cell?.imageView?.image = page.image;
        }
        
        return cell!;
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
//        if let image = convertPDFToImage(atPageIndex: indexPath.row + 1) {
//            pdfPages.insert(image, at: indexPath.row)
//            tableView.reloadData()
//        }
    }
}


extension ConvertViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return pdfPages.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! PDFPageCell
        
        let page = pdfPages[indexPath.item]
//        cell.setupPageInfo(newPageInfo: page)
        cell.setupPageInfo(newPageInfo: page, enableSelect: enableSelectPage)
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        collectionView.deselectItem(at: indexPath, animated: true)
        
        let page = pdfPages[indexPath.item]
        
        if enableSelectPage {
            page.isSelected = !page.isSelected
            
            updateSelectedPagesInfo()
            collectionView.reloadData()
        }else {
            Tracker.previewPages()
            
//            Toast.showMessage(message: String(format: "Preview page %d", page.index!))
            let browser = SKPhotoBrowser(photos: createSKPhotos())
            browser.initializePageIndex(indexPath.item)
            browser.delegate = self
            
            present(browser, animated: true, completion: nil)
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        
        if enableSelectPage {
            return
        }
        
        let lastElement = pdfPages.count - 1
        if indexPath.row == lastElement {
            // handle your logic here to get more items, add it to dataSource and reload tableview
            if let url = pdfURL {
                self.loadPDF(fileURL: url, startAt: lastElement+1, length: 20)
            }
        }
    }
    
    
}


extension ConvertViewController: SKPhotoBrowserDelegate {
    func willShowActionSheet(_ photoIndex: Int) {
        print("分享：\(photoIndex)")
        Tracker.sharePage(docName: (pdfURL?.lastPathComponent)!)
    }
}
